package com.hc.security.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hc.security.config.security.UrlResponse;
import com.hc.security.entity.AuthorityMenu;
import com.hc.security.entity.AuthorityRoleMenu;
import com.hc.security.entity.AuthorityUser;
import com.hc.security.entity.AuthorityUserRole;
import com.hc.security.mapper.*;
import com.hc.springtools.security.mapper.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@SuppressWarnings("Duplicates")
@Service
public class UserServiceImpl {

    private static final Logger LOG = LoggerFactory.getLogger(UserServiceImpl.class);

    @Resource
    private AuthorityUserMapper authorityUserMapper;
    @Resource
    private AuthorityUserRoleMapper authorityUserRoleMapper;
    @Resource
    private AuthorityRoleMapper authorityRoleMapper;
    @Resource
    private AuthorityMenuMapper authorityMenuMapper;
    @Resource
    private AuthorityRoleMenuMapper authorityRoleMenuMapper;

    public String findPasswordByUsername(String username) {
        AuthorityUser user = authorityUserMapper.selectOne(
                new QueryWrapper<AuthorityUser>().eq("username", username));
        if (ObjUtil.isNotEmpty(user)){
            return user.getPassword();
        }
        return null;
    }

    public List<String> findRoleNameByUsername(String username) {
        Integer userId = authorityUserMapper.selectOne(
                new QueryWrapper<AuthorityUser>().eq("username", username)).getId();
        List<AuthorityUserRole> userRolesList = authorityUserRoleMapper.selectList(new QueryWrapper<AuthorityUserRole>().eq("user_id", userId));
        if (CollUtil.isNotEmpty(userRolesList)){
            return userRolesList.stream().map(item->
                    authorityRoleMapper.selectById(item.getRoleId()).getRoleName()).collect(Collectors.toList());
        }
        return null;
    }

    public List<String> findAllMenuUrl() {
        return authorityMenuMapper.selectList(
                new QueryWrapper<AuthorityMenu>()).stream()
                .map(AuthorityMenu::getUrl)
                .collect(Collectors.toList());
    }

    public List<String> findRoleNameByMenuUrl(String url) {
        Integer menuId = authorityMenuMapper.selectOne(
                new QueryWrapper<AuthorityMenu>().eq("url", url)).getId();
        return authorityRoleMenuMapper.selectList(
                new QueryWrapper<AuthorityRoleMenu>().eq("menu_id",menuId)).stream()
                .map(item-> authorityRoleMapper.selectById(item.getRoleId()).getRoleName())
                .collect(Collectors.toList());
    }

    public Map<String, Object> findMenuInfoByUsername(String username, UrlResponse response) {
        AuthorityUser user = authorityUserMapper.selectOne(new QueryWrapper<AuthorityUser>().eq("username", username));
        // 判断是否最高权限
        List<AuthorityUserRole> userRoles = authorityUserRoleMapper.selectList(new QueryWrapper<AuthorityUserRole>().eq("user_id", user.getId()));
        ArrayList<String> listUrl = new ArrayList<>();
        if (CollUtil.isNotEmpty(userRoles)) {
            for (AuthorityUserRole userRole : userRoles) {
                List<AuthorityRoleMenu> roleMenus= authorityRoleMenuMapper.selectList(new QueryWrapper<AuthorityRoleMenu>().eq("role_id", userRole.getRoleId()));
                if (CollUtil.isNotEmpty(roleMenus)){
                    for (AuthorityRoleMenu roleMenu : roleMenus) {
                        AuthorityMenu menu = authorityMenuMapper.selectOne(new QueryWrapper<AuthorityMenu>().eq("id", roleMenu.getMenuId()));
                        listUrl.add(menu.getUrl());
                    }
                }
            }
        }
        boolean isHighestAuthority = listUrl.contains("/**");
        return null;
    }
}
